package com.ecarx.vhaltests.hy11.testcases.brightness;

import android.car.VehicleAreaSeat;
import android.car.VehicleAreaType;
import android.car.hardware.CarPropertyConfig;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;
import com.ecarx.xui.adaptapi.automotive.VehicleArea;
import com.ecarx.xui.adaptapi.automotive.VehiclePropertyGroup;
import com.ecarx.xui.adaptapi.automotive.VehiclePropertyType;
import com.ecarx.xui.adaptapi.car.IWrapper;
import com.ecarx.xui.adaptapi.car.vehicle.IDayMode;

import androidx.test.platform.app.InstrumentationRegistry;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;


@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SettingFuncBrightnessDIMTest extends VhalUnitTestBase {

    private static final String TAG = "SettingFuncBrightnessDIMTest";

    private static int mPropertyId =  -1;


    private static final int mAREA = VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
    private static final int mglobal_AREA = VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;

    private static final int SERVICE_ID_VGM = 49;
    private static final int OP_ID_VGM = 999;


    @BeforeClass
    public static void testInit() {
        IWrapper wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        mPropertyId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, IDayMode.SETTING_FUNC_BRIGHTNESS_DIM).getPropertyId();

        delay();
    }


    @Test
    public void testDimBrightSetAndGetDay() {
        testDimBrightreboot();
        //mock day
        setCarConfig(true);
        mockDayNightTwliBriSts(true);
        delay();

        CarPropertyConfig config = mCarPropertyMgr.getCarPropertyConfig(mPropertyId);
        Assert.assertEquals(config.getMaxValue(mAREA) ,15);
        Assert.assertEquals(config.getMinValue(mAREA) ,0);
        
   
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 8);
        delay();
        int brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(brightness ,8);

        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, -2);
        delay();
        brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(brightness ,0);

        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 16);
        delay();
        brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(brightness ,15);


        mockDayNightTwliBriSts(true);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 10);

        mockDayNightTwliBriSts(false);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 5);

        mockDayNightTwliBriSts(true);
        delay();
        brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(brightness ,10);
    }

    @Test
    public void testDimBrightSetAndGetNight () {
        testDimBrightreboot();

        setCarConfig(true);
        mockDayNightTwliBriSts(false);
        delay();

        CarPropertyConfig config = mCarPropertyMgr.getCarPropertyConfig(mPropertyId);

        Assert.assertEquals(config.getMaxValue(mAREA) ,15);

        Assert.assertEquals(config.getMinValue(mAREA) ,0);
        
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 8);
        delay();
        int brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(brightness ,8);


        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, -2);
        delay();
        brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(brightness ,0);

        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 16);
        delay();
        brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(brightness ,15);

        mockDayNightTwliBriSts(false);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 6);

        mockDayNightTwliBriSts(true);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 9);

        mockDayNightTwliBriSts(false);
        delay();
        brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(brightness ,6);
    }

    private static  int mCallbackValue = -1;
    @Test
    public void testDimBrightCallback() {
        testDimBrightreboot();

        setCarConfig(true);
        CarPropertyManager.CarPropertyEventCallback mCallback = new CarPropertyManager.CarPropertyEventCallback() {
            @Override
            public void onChangeEvent(CarPropertyValue carPropertyValue) {
                mCallbackValue = (int) carPropertyValue.getValue();
            }

            @Override
            public void onErrorEvent(int i, int i1) {

            }
        };
        mockDayNightTwliBriSts(true);
        delay();
        boolean ret = mCarPropertyMgr.registerCallback(mCallback, mPropertyId, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        delay();
        Assert.assertTrue(ret);
        mCarPropertyMgr.unregisterCallback(mCallback, mPropertyId);
        delay();


        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 5);
        mCallbackValue = -1;
        mCarPropertyMgr.registerCallback(mCallback, mPropertyId, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 10);
        delay(2000);
        Assert.assertEquals(mCallbackValue ,10);
        delay();
        mCarPropertyMgr.unregisterCallback(mCallback, mPropertyId);
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 12);
        delay(2000);
        Assert.assertEquals(mCallbackValue ,10);


        mockDayNightTwliBriSts(false);
        delay();
        ret = mCarPropertyMgr.registerCallback(mCallback, mPropertyId, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        delay();
        Assert.assertTrue(ret);
        mCarPropertyMgr.unregisterCallback(mCallback, mPropertyId);
        delay();

        
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 5);
        mCallbackValue = -1;
        mCarPropertyMgr.registerCallback(mCallback, mPropertyId, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 10);
        delay(2000);
        Assert.assertEquals(mCallbackValue ,10);
        delay();
        mCarPropertyMgr.unregisterCallback(mCallback, mPropertyId);
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 12);
        delay(2000);
        Assert.assertEquals(mCallbackValue ,10);


        mockDayNightTwliBriSts(true);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 10);

        mockDayNightTwliBriSts(false);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 5);

        mCallbackValue = -1;
        mCarPropertyMgr.registerCallback(mCallback, mPropertyId, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        delay();

        mockDayNightTwliBriSts(true);
        delay(2000);
        Assert.assertEquals(mCallbackValue ,10);
        
        delay();

        mockDayNightTwliBriSts(false);
        delay(2000);
        Assert.assertEquals(mCallbackValue ,5);  
        
        mCarPropertyMgr.unregisterCallback(mCallback, mPropertyId);
    }

    @Test
    public void testDimBrightAvailable() {

        setCarConfig(true);
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(mPropertyId, mAREA);
        Log.d(TAG, "isAvail:" + isAvail);
        Assert.assertTrue(isAvail);
        delay();
        setCarConfig(false);
        isAvail = mCarPropertyMgr.isPropertyAvailable(mPropertyId, mAREA);
        Assert.assertFalse(isAvail);
    }

    @Test
    public void testDimBrightWakeupVFC() {

        setCarConfig(true);
        
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 10);
        delay();
        setUsgModAband(true);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 11);
        delay();
 
        setUsgModAband(false);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 12);
        delay();
    }
    public void testDimBrightreboot() {

        setCarConfig(true);
        mockDayNightTwliBriSts(true);

        delay();
        int brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Log.d(TAG, "SETTING_FUNC_BRIGHTNESS_DIM testDimBrightreboot day:" + brightness);

    }
    public void setCarConfig(boolean isDIMActive) {
        IpcpClient ipcpClient = new IpcpClient();
        int ccSvcId = 135;
        int ccOperId = 200;
        int[] configs = {546};
        int[] values = {isDIMActive?2:1};
        ipcpClient.setConfig(ccSvcId, new int[]{ccOperId});
        boolean ccResult = ipcpClient.setCarconfigSignal(ccSvcId, ccOperId, configs, values);
        Assert.assertTrue(ccResult);
        delay();
    }


    private static void mockDayNightTwliBriSts(boolean isday) {
        IpcpClient ipcpClient = new IpcpClient();
        int cemSvcId = 37;
        int cemOperId = 999;
        int[] cemOperIds = {cemOperId};
        ipcpClient.setConfig(cemSvcId, cemOperIds);
        String[] cems = {"twliBriSts"};
        int[] cemValues = {isday ? 1 : 0};
        boolean dd = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        Log.d(TAG, "SETTING_FUNC_BRIGHTNESS_DIM mockDayNightTwliBriSts setVGMSignal:" + dd +  ",isday:" + isday);
        delay();
    }

    private static void setUsgModAband(boolean isAband) {
        IpcpClient ipcpClient = new IpcpClient();
        int cemSvcId = 37;
        int cemOperId = 999;
        int[] cemOperIds = {cemOperId};
        ipcpClient.setConfig(cemSvcId, cemOperIds);
        String[] cems = {"vehModMngtGlbSafe1CarModSts1", "vehModMngtGlbSafe1UsgModSts"};
        int[] cemValues = {VehicleConstants.CAR_MODE_NOMAL, isAband?VehicleConstants.USG_MODE_ABANDON:VehicleConstants.USG_MODE_DRIVING};
        boolean cemResult = ipcpClient.setCEMSignal(cemSvcId, cemOperId, cems, cemValues);
        Assert.assertTrue(cemResult);
        delay();
    }

}       